package com.aaa.sso.config;

import com.aaa.entity.LoginLog;
import com.aaa.sso.service.LoginLogService;
import com.aaa.sso.service.UserService;
import com.aaa.util.JwtUtil;
import com.aaa.vo.Result;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;

import java.io.PrintWriter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @Author 崔灿
 * @Date 2023/02/25 10:11
 * @ClassName MySecurityConfig
 * @Description
 * @Version 1.0
 */

@Configuration
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private UserService userService;

    @Autowired
    private LoginLogService loginLogService;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Bean
    public PasswordEncoder passwordEncoder() {
        //加盐加密: 原密码+盐===>哈希加密===>密文
        //   原密码===>哈希加密===>密文 [存储大量常见的密文]
        //123456+随机产生盐===>密文
        return new BCryptPasswordEncoder();
    }


    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.formLogin()
                .successHandler(successHandler())
                .failureHandler(failureHandler())
                .loginProcessingUrl("/login").permitAll();

        http.cors();
        http.csrf().disable();
        http.authorizeRequests().anyRequest().authenticated();

    }

    private AuthenticationSuccessHandler successHandler() {
        return (request, response, authentication) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();
            //获取账号和权限
            User principal = (User)authentication.getPrincipal();
            String username = principal.getUsername();
            Collection<String> authorities = authentication.getAuthorities().stream().map(item->item.getAuthority()).collect(Collectors.toList());
            //根据账号和权限生产token;
            Map<String,Object> map=new HashMap<>();
            map.put("username",username);
            map.put("authorities",authorities);
            String token = JwtUtil.createJWT(map);

            //存入redis中。
            redisTemplate.opsForValue().set(token,"",30, TimeUnit.MINUTES);

            Result<String> result=new Result<>(2000,"登录成功",token);
            String jsonString = JSON.toJSONString(result);

            String remoteAddr = request.getRemoteAddr();

            String  browserDetails  =   request.getHeader("User-Agent");
            String  userAgent       =   browserDetails;
            String  user            =   userAgent.toLowerCase();

            String os = "";
            String browser = "";

            //=================OS Info=======================
            if (userAgent.toLowerCase().indexOf("windows") >= 0 )
            {
                os = "Windows";
            } else if(userAgent.toLowerCase().indexOf("mac") >= 0)
            {
                os = "Mac";
            } else if(userAgent.toLowerCase().indexOf("x11") >= 0)
            {
                os = "Unix";
            } else if(userAgent.toLowerCase().indexOf("android") >= 0)
            {
                os = "Android";
            } else if(userAgent.toLowerCase().indexOf("iphone") >= 0)
            {
                os = "IPhone";
            }else{
                os = "UnKnown, More-Info: "+userAgent;
            }
            //===============Browser===========================
            if (user.contains("edge"))
            {
                browser=(userAgent.substring(userAgent.indexOf("Edge")).split(" ")[0]).replace("/", "-");
            } else if (user.contains("msie"))
            {
                String substring=userAgent.substring(userAgent.indexOf("MSIE")).split(";")[0];
                browser=substring.split(" ")[0].replace("MSIE", "IE")+"-"+substring.split(" ")[1];
            } else if (user.contains("safari") && user.contains("version"))
            {
                browser=(userAgent.substring(userAgent.indexOf("Safari")).split(" ")[0]).split("/")[0]
                        + "-" +(userAgent.substring(userAgent.indexOf("Version")).split(" ")[0]).split("/")[1];
            } else if ( user.contains("opr") || user.contains("opera"))
            {
                if(user.contains("opera")){
                    browser=(userAgent.substring(userAgent.indexOf("Opera")).split(" ")[0]).split("/")[0]
                            +"-"+(userAgent.substring(userAgent.indexOf("Version")).split(" ")[0]).split("/")[1];
                }else if(user.contains("opr")){
                    browser=((userAgent.substring(userAgent.indexOf("OPR")).split(" ")[0]).replace("/", "-"))
                            .replace("OPR", "Opera");
                }

            } else if (user.contains("chrome"))
            {
                browser=(userAgent.substring(userAgent.indexOf("Chrome")).split(" ")[0]).replace("/", "-");
            } else if ((user.indexOf("mozilla/7.0") > -1) || (user.indexOf("netscape6") != -1)  ||
                    (user.indexOf("mozilla/4.7") != -1) || (user.indexOf("mozilla/4.78") != -1) ||
                    (user.indexOf("mozilla/4.08") != -1) || (user.indexOf("mozilla/3") != -1) )
            {
                browser = "Netscape-?";

            } else if (user.contains("firefox"))
            {
                browser=(userAgent.substring(userAgent.indexOf("Firefox")).split(" ")[0]).replace("/", "-");
            } else if(user.contains("rv"))
            {
                String IEVersion = (userAgent.substring(userAgent.indexOf("rv")).split(" ")[0]).replace("rv:", "-");
                browser="IE" + IEVersion.substring(0,IEVersion.length() - 1);
            } else
            {
                browser = "UnKnown, More-Info: "+userAgent;
            }

            LoginLog loginLog1 = new LoginLog();
            loginLog1.setLoginName(username);
            loginLog1.setIpaddr(remoteAddr);
            loginLog1.setBrowser(browser);
            loginLog1.setOs(os);
            loginLog1.setStatus(1);
            loginLog1.setMsg("登录成功");
            loginLog1.setLoginTime(new Date());
            loginLogService.addLoginLog(loginLog1);

            writer.write(jsonString);
            writer.flush();
            writer.close();
        };
    }

    private AuthenticationFailureHandler failureHandler() {
        return (request, response, e) -> {
            response.setContentType("application/json;charset=utf-8");
            PrintWriter writer = response.getWriter();


            Result<String> result=new Result<>(5000,"登录失败");
            String jsonString = JSON.toJSONString(result);


            writer.print(jsonString);
            writer.flush();
            writer.close();
        };
    }

    public static void main(String[] args) {
        BCryptPasswordEncoder passwordEncoder=new BCryptPasswordEncoder();
        System.out.println(passwordEncoder.encode("123456"));

    }
}


